package me.android.library.common.ipc;


import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.*;
import android.util.Log;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 通用 IPC 服务基类
 * 使用 Messenger 实现跨进程通信，支持命令分发和回调机制
 */
public abstract class IpcService extends Service {
    private static final String TAG = "IpcService";
    public static final int MSG_COMMAND = 1001;       // 普通命令消息
    public static final int MSG_REGISTER_CLIENT = 1002; // 注册客户端
    public static final int MSG_UNREGISTER_CLIENT = 1003; // 注销客户端
    public static final String KEY_COMMAND = "command";  // 命令名称
    public static final String KEY_PARAMS = "params";    // 参数
    public static final String KEY_CALLBACK = "callback"; // 回调 Messenger

    // 注册的客户端集合（线程安全）
    private final ConcurrentHashMap<Integer, Messenger> clients = new ConcurrentHashMap<>();
    private int nextClientId = 0;

    // 服务端 Messenger
    private final Messenger serviceMessenger = new Messenger(new ServiceHandler());

    // 处理客户端消息的 Handler
    @SuppressLint("HandlerLeak")
    private class ServiceHandler extends Handler {
        public ServiceHandler() {
            super(Looper.getMainLooper());
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_COMMAND:
                    handleCommand(msg);
                    break;
                case MSG_REGISTER_CLIENT:
                    registerClient(msg);
                    break;
                case MSG_UNREGISTER_CLIENT:
                    unregisterClient(msg);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    // 处理命令消息
    private void handleCommand(Message msg) {
        String command = msg.getData().getString(KEY_COMMAND);
        if (command == null) return;

        Bundle params = msg.getData().getBundle(KEY_PARAMS);
        Messenger callback = msg.replyTo != null ? msg.replyTo :
                msg.getData().getParcelable(KEY_CALLBACK);

        Log.d(TAG, "收到命令: " + command + ", 来自: " + msg.replyTo);

        // 在子类中实现命令处理逻辑
        handleIpcCommand(command, params, new IpcCallback() {
            @Override
            public void onSuccess(Bundle result) {
                sendReply(msg, 200, "成功", result, callback);
            }

            @Override
            public void onError(int code, String message, Bundle data) {
                sendReply(msg, code, message, data, callback);
            }
        });
    }

    // 发送回复消息
    private void sendReply(Message originalMsg, int code, String message, Bundle data, Messenger callback) {
        if (callback == null) return;

        Message reply = Message.obtain(null, originalMsg.what);
        Bundle replyData = new Bundle();
        replyData.putInt("code", code);
        replyData.putString("message", message);
        replyData.putBundle("data", data);
        reply.setData(replyData);

        try {
            callback.send(reply);
        } catch (RemoteException e) {
            Log.e(TAG, "发送回复失败: " + e.getMessage());
        }
    }

    // 注册客户端
    private void registerClient(Message msg) {
        int clientId = nextClientId++;
        if (msg.replyTo != null) {
            clients.put(clientId, msg.replyTo);
            Log.d(TAG, "客户端已注册, ID: " + clientId);

            // 返回客户端 ID
            Message reply = Message.obtain(null, MSG_REGISTER_CLIENT);
            Bundle data = new Bundle();
            data.putInt("clientId", clientId);
            reply.setData(data);

            try {
                msg.replyTo.send(reply);
            } catch (RemoteException e) {
                Log.e(TAG, "注册客户端失败: " + e.getMessage());
            }
        }
    }

    // 注销客户端
    private void unregisterClient(Message msg) {
        int clientId = msg.getData().getInt("clientId", -1);
        if (clientId != -1) {
            clients.remove(clientId);
            Log.d(TAG, "客户端已注销, ID: " + clientId);
        }
    }

    // 向所有客户端广播消息
    protected void broadcastMessage(String command, Bundle params) {
        Message msg = Message.obtain(null, MSG_COMMAND);
        Bundle data = new Bundle();
        data.putString(KEY_COMMAND, command);
        data.putBundle(KEY_PARAMS, params);
        msg.setData(data);

        for (Messenger client : clients.values()) {
            try {
                client.send(msg);
            } catch (RemoteException e) {
                Log.e(TAG, "广播消息失败: " + e.getMessage());
            }
        }
    }

    // 向指定客户端发送消息
    protected void sendMessageToClient(int clientId, String command, Bundle params) {
        Messenger client = clients.get(clientId);
        if (client == null) {
            Log.e(TAG, "客户端不存在, ID: " + clientId);
            return;
        }

        Message msg = Message.obtain(null, MSG_COMMAND);
        Bundle data = new Bundle();
        data.putString(KEY_COMMAND, command);
        data.putBundle(KEY_PARAMS, params);
        msg.setData(data);

        try {
            client.send(msg);
        } catch (RemoteException e) {
            Log.e(TAG, "发送消息到客户端失败: " + e.getMessage());
        }
    }

    // 由子类实现的命令处理方法
    protected abstract void handleIpcCommand(String command, Bundle params, IpcCallback callback);

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "服务已绑定");
        return serviceMessenger.getBinder();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        clients.clear();
        Log.d(TAG, "服务已销毁");
    }


    /**
     * 在 AndroidManifest.xml 中声明服务<p>
     * <service
     *     android:name=".MyIpcService"
     *     android:enabled="true"
     *     android:exported="true"
     *     android:permission="android.permission.BIND_SERVICE">
     *     <intent-filter>
     *         <action android:name="com.example.ipc.MY_IPC_SERVICE" />
     *     </intent-filter>
     * </service>
     */
    public static class DemoIpcService extends IpcService {
        private static final String TAG = "DemoIpcService";

        @Override
        protected void handleIpcCommand(String command, Bundle params, IpcCallback callback) {
            switch (command) {
                case "GET_DATA":
                    Bundle result = new Bundle();
                    result.putString("data", "这是服务端数据");
                    callback.onSuccess(result);
                    break;
                case "SAVE_DATA":
                    String data = params != null ? params.getString("input") : "";
                    Log.d(TAG, "保存数据: " + data);
                    callback.onSuccess(null);
                    break;
                default:
                    callback.onError(404, "未知命令", null);
                    break;
            }
        }
    }
}
